package service

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"thriftbam/models"
	"thriftbam/parser"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

var (
	a models.Arguments
)

type ThriftFileService struct {
	c   context.Context
	ctx *app.RequestContext
}

func NewThriftFileService(c context.Context, ctx *app.RequestContext) *ThriftFileService {
	return &ThriftFileService{c: c, ctx: ctx}
}

func Ping(c context.Context, ctx *app.RequestContext) {
	ctx.JSON(consts.StatusOK, utils.H{"message": "pong"})
}

func (t *ThriftFileService) AnalyzeIDL(userRequest *models.UserRequest) (msg string, err error) {

	var id string = userRequest.ID
	var ack string = userRequest.Ack
	var owner string = userRequest.Owner
	var repo string = userRequest.Repo
	var path string = userRequest.Path
	var ref string = userRequest.Ref
	var dirPath string = "thriftbam/" + id + "/"
	url := "https://gitee.com/api/v5/repos/" + owner + "/" + repo + "/contents/" + path + "?access_token=" + ack + "&ref=" + ref
	// user := models.NewUserRequest(id, owner, repo, path, ref, ack)
	// 发起 GET 请求
	resp, err := http.Get(url)
	if err != nil {
		fmt.Println("Failed to send request:", err)
		return
	}

	// 读取响应内容
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Failed to read response body:", err)
		return
	}
	// 定义切片来存储解析后的数据
	var contents []models.Content
	// 解析 JSON 数据
	err = json.Unmarshal(body, &contents)
	if err != nil {
		fmt.Println("Failed to unmarshal JSON:", err)
		return
	}
	resp.Body.Close()
	downloadFile(contents, id, dirPath)

	// 打开目录
	dir, err := os.Open(dirPath)
	if err != nil {
		fmt.Println("Failed to open directory:", err)
		return
	}
	// 读取目录中的文件列表
	fileInfos, err := dir.Readdir(-1)
	if err != nil {
		fmt.Println("Failed to read directory contents:", err)
		return
	}
	// 遍历文件列表
	for _, fileInfo := range fileInfos {
		a.IDL = dirPath + fileInfo.Name()
		ast, _ := parser.ParseFile(a.IDL, a.Includes, true)

		if path := parser.CircleDetect(ast); len(path) > 0 {
			check(fmt.Errorf("found include circle:\n\t%s", path))
		}
	}
	dir.Close()

	// 删除目录
	err = os.RemoveAll(dirPath)
	if err != nil {
		fmt.Println("Failed to remove directory:", err)
		return
	}
	return "ok", nil
}

func downloadFile(contents []models.Content, id string, dirPath string) {

	// 创建目录
	err := os.MkdirAll(dirPath, 0755)
	if err != nil {
		fmt.Println("Failed to create directory:", err)
		return
	}
	for _, c := range contents {
		download_url := c.DownloadURL
		resp, err := http.Get(download_url)
		if err != nil {
			fmt.Println("Failed to send request:", err)
			return
		}
		// 创建目标文件
		filePath := filepath.Join(dirPath, c.Name)
		file, err := os.Create(filePath)
		if err != nil {
			fmt.Println("Failed to create file:", err)
			resp.Body.Close()
			continue
		}
		// 将响应内容写入文件
		_, err = io.Copy(file, resp.Body)
		if err != nil {
			fmt.Println("Failed to write to file:", err)
			file.Close()
			resp.Body.Close()
			continue
		}
		// 关闭文件句柄
		file.Close()
		resp.Body.Close()
	}
}

func check(err error) {
	if err != nil {
		println(err.Error())
	}
}
